package com.ruoyi.project.modules.interfaceinfo.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysDictType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.project.modules.interfaceinfo.domain.InterfaceInfo;
import com.ruoyi.project.modules.interfaceinfo.domain.VirtualUsage;
import com.ruoyi.project.modules.interfaceinfo.service.IInterfaceInfoService;
import com.ruoyi.project.modules.interfaceinfo.service.IVirtualUsageService;
import com.ruoyi.project.modules.interfaceinfo.vo.InterfaceParam;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.system.service.ISysDictTypeService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * TODO
 *
 * @author chenxiaoyu
 * @version 1.0
 * @date 2022/1/16 下午11:31
 */
@RestController
@RequestMapping("/")
public class InterfaceMockController {

    @Resource
    private IInterfaceInfoService interfaceInfoService;

    @Resource
    private IVirtualUsageService virtualUsageService;

    @Resource
    private ISysDictDataService sysDictDataService;

    @Resource
    private ISysDictTypeService sysDictTypeService;

    @RequestMapping("/mock/**")
    @ResponseBody
    public Map<String, Object> mock(HttpServletRequest request) {
        Map<String, Object> mock = new HashMap<>();
        InterfaceInfo interfaceInfo = new InterfaceInfo();
        String requestURI = request.getRequestURI();
        if (requestURI.length() > 5) {
            interfaceInfo.setInterfaceUrl(requestURI.substring(5));
            List<InterfaceInfo> interfaceInfoList = this.interfaceInfoService.selectInterfaceInfoList(interfaceInfo);
            if (CollectionUtil.isNotEmpty(interfaceInfoList)) {
                InterfaceInfo info = interfaceInfoList.get(0);
                String fbType = info.getFbType();
                if (fbType.equals("3")) {
                    fbType = "4";
                }
                mock.put("errCode", "1");
                mock.put("message", "获取成功");

                List<InterfaceParam> responseList = this.interfaceInfoService.paramList(fbType, info.getId(), "2");
                if (CollectionUtil.isNotEmpty(responseList)) {
                    if (responseList.size() == 1) {
                        InterfaceParam interfaceParam1 = responseList.get(0);
                        if ("Y".equals(interfaceParam1.getIsTree())) {
                            if (interfaceParam1.getChildren() == null) {
                                interfaceParam1.setChildren(new ArrayList<>());
                            }
                            addFixedValue(interfaceParam1.getChildren());
                            InterfaceParam newObject = JSONObject.parseObject(JSONObject.toJSONString(interfaceParam1), InterfaceParam.class);
                            newObject.setFieldName("子列表");
                            newObject.setFieldEnName("children");

                            interfaceParam1.setFieldEnName("treeNode");
                            interfaceParam1.getChildren().add(newObject);
                            responseList = Arrays.asList(interfaceParam1);
                        }
                    } else if (responseList.size() == 2) {
                        InterfaceParam interfaceParam1 = responseList.get(0);
                        InterfaceParam interfaceParam2 = responseList.get(1);
                        if ("Y".equals(interfaceParam1.getIsTree())) {
                            if (interfaceParam1.getChildren() == null) {
                                interfaceParam1.setChildren(new ArrayList<>());
                            }
                            addFixedValue(interfaceParam1.getChildren());
                            InterfaceParam newObject = JSONObject.parseObject(JSONObject.toJSONString(interfaceParam1), InterfaceParam.class);
                            newObject.setFieldName("子列表");
                            newObject.setFieldEnName("children");
                            interfaceParam1.getChildren().add(newObject);
                            interfaceParam1.setFieldEnName("treeNode");
                            responseList = Arrays.asList(interfaceParam1);
                        }
                        if ("Y".equals(interfaceParam2.getIsTree())) {
                            if (interfaceParam2.getChildren() == null) {
                                interfaceParam2.setChildren(new ArrayList<>());
                            }
                            addFixedValue(interfaceParam2.getChildren());
                            InterfaceParam newObject = JSONObject.parseObject(JSONObject.toJSONString(interfaceParam2), InterfaceParam.class);
                            newObject.setFieldName("子列表");
                            newObject.setFieldEnName("children");
                            interfaceParam2.getChildren().add(newObject);
                            interfaceParam2.setFieldEnName("treeNode");
                            responseList = Arrays.asList(interfaceParam2);
                        }
                        if (StringUtils.isNotEmpty(interfaceParam1.getNodeType()) && StringUtils.isNotEmpty(interfaceParam2.getNodeType())) {
                            if ("F".equals(interfaceParam1.getNodeType()) && "Z".equals(interfaceParam2.getNodeType())) {
                                if (interfaceParam1.getChildren() == null) {
                                    interfaceParam1.setChildren(new ArrayList<>());
                                }
                                if ("Y".equals(interfaceParam1.getIsTree())) {
                                    for (InterfaceParam child : interfaceParam1.getChildren()) {
                                        if ("2".equals(child.getObjectType())) {
                                            if (child.getChildren() == null) {
                                                child.setChildren(new ArrayList<>());
                                            }
                                            interfaceParam2.setFieldEnName("children");
                                            //interfaceParam2.setFieldName("子列表");
                                            child.getChildren().add(interfaceParam2);
                                            break;
                                        }
                                    }
                                } else {
                                    interfaceParam2.setFieldEnName("children");
                                    interfaceParam2.setFieldName("子列表");
                                    interfaceParam1.getChildren().add(interfaceParam2);
                                }
                                responseList = Arrays.asList(interfaceParam1);
                            } else if ("Z".equals(interfaceParam1.getNodeType()) && "F".equals(interfaceParam2.getNodeType())) {
                                if (interfaceParam2.getChildren() == null) {
                                    interfaceParam2.setChildren(new ArrayList<>());
                                }
                                if ("Y".equals(interfaceParam2.getIsTree())) {
                                    for (InterfaceParam child : interfaceParam2.getChildren()) {
                                        if ("2".equals(child.getObjectType())) {
                                            if (child.getChildren() == null) {
                                                child.setChildren(new ArrayList<>());
                                            }
                                            interfaceParam1.setFieldEnName("children");
                                            //interfaceParam1.setFieldName("子列表");
                                            child.getChildren().add(interfaceParam1);
                                            break;
                                        }
                                    }
                                } else {
                                    interfaceParam1.setFieldEnName("children");
                                    interfaceParam1.setFieldName("子列表");
                                    interfaceParam2.getChildren().add(interfaceParam1);
                                }
                                responseList = Arrays.asList(interfaceParam2);
                            }
                        }
                    }

                    if ("Y".equals(info.getIsPage())) {
                        InterfaceParam interfaceParam3 = new InterfaceParam();
                        interfaceParam3.setFieldEnName("total");
                        interfaceParam3.setFieldName("总条数");
                        interfaceParam3.setMockData(1000);
                        interfaceParam3.setObjectType("1");
                        responseList.add(interfaceParam3);
                        InterfaceParam interfaceParam4 = new InterfaceParam();
                        interfaceParam4.setFieldEnName("isLastPage");
                        interfaceParam4.setFieldName("是否最后一页");
                        interfaceParam4.setMockData(true);
                        interfaceParam4.setObjectType("1");
                        responseList.add(interfaceParam4);

                        InterfaceParam interfaceParam5 = new InterfaceParam();
                        interfaceParam5.setFieldEnName("pages");
                        interfaceParam5.setFieldName("总页数");
                        interfaceParam5.setMockData(10);
                        interfaceParam5.setObjectType("1");
                        responseList.add(interfaceParam5);
                    }

                    if (responseList.size() == 1 && false) {
                        InterfaceParam interfaceParam = responseList.get(0);
                        if (CollectionUtil.isEmpty(interfaceParam.getChildren())) {
                            mock.put("data", interfaceParam.getMockData());
                        } else {
                            List<InterfaceParam> children = interfaceParam.getChildren();
                            if (children.size() == 1) {
                                mock.put("data", Collections.singletonList(children.get(0).getMockData()));
                            } else {
                                List<Map<String, Object>> data = new ArrayList<>();
                                mock.put("data", data);
                                for (int i=0; i< 30; i++) {
                                    Map<String, Object> map = new HashMap<>();
                                    for (InterfaceParam childInterfaceParam : children) {
                                        if (CollectionUtil.isNotEmpty(childInterfaceParam.getChildren())) {
                                            List<Map<String, Object>> child = new ArrayList<>();
                                            Map<String, Object> mapChild = new HashMap<>();
                                            for (InterfaceParam interfaceParamChild : childInterfaceParam.getChildren()) {
                                                mapChild.put(interfaceParamChild.getFieldEnName(), getMockData(interfaceParamChild, (30 + i)));
                                            }
                                            child.add(mapChild);
                                            map.put(childInterfaceParam.getFieldEnName(), child);
                                        } else {
                                            map.put(childInterfaceParam.getFieldEnName(), getMockData(childInterfaceParam, i));
                                        }
                                    }
                                    data.add(map);
                                }
                            }
                        }
                    } else {
                        Map<String, Object> data = new HashMap<>();
                        mock.put("data", data);
                        convertMap(responseList, data, 1);
                    }
                } else {
                    List<Map<String, Object>> data = new ArrayList<>();
                    mock.put("data", data);
                }
            }
        }
        return mock;
    }

    private void convertMap(List<InterfaceParam> interfaceParamList, Map<String, Object> data, int index) {
        if (CollectionUtil.isEmpty(interfaceParamList)) return;
        String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        for (InterfaceParam interfaceParam : interfaceParamList) {
            if (interfaceParam.getObjectType().equals("1")) {
                if ("时间".equals(interfaceParam.getFieldDataType())) {
                    data.put(interfaceParam.getFieldEnName(), format);
                } else {
                    data.put(interfaceParam.getFieldEnName(), interfaceParam.getMockData());
                }
            } else {
                List<Object> dataMap = new ArrayList<>();
                for (int i = 0; i < 15; i++) {
                    if (CollectionUtil.isNotEmpty(interfaceParam.getChildren())) {
                        Map<String, Object> child = new HashMap<>();
                        dataMap.add(child);
                        for (InterfaceParam interfaceParamChild : interfaceParam.getChildren()) {
                            if (interfaceParamChild.getObjectType().equals("1")) {
                                if ("actualFromLastTime".equals(interfaceParamChild.getFieldEnName())||
                                        "progressFromLastTime".equals(interfaceParamChild.getFieldEnName()) ||
                                        "progressValue".equals(interfaceParamChild.getFieldEnName())||
                                        "reach".equals(interfaceParamChild.getFieldEnName())) {
                                    child.put(interfaceParamChild.getFieldEnName(), interfaceParamChild.getMockData());
                                } else if ("时间".equals(interfaceParamChild.getFieldDataType())) {
                                    child.put(interfaceParamChild.getFieldEnName(), format);
                                } else {
                                    child.put(interfaceParamChild.getFieldEnName(), getMockData(interfaceParamChild, (30 * index + i)));
                                }
                            } else {
                                List<Object> dataMap2 = new ArrayList<>();
                                Map<String, Object> c = new HashMap<>();
                                dataMap2.add(c);
                                convertMap(interfaceParamChild.getChildren(), c, ++index);
                                child.put(interfaceParamChild.getFieldEnName(), dataMap2);
                            }
                        }
                    }
                }
                data.put(interfaceParam.getFieldEnName(), dataMap);
            }
        }
    }

    private void addFixedValue(List<InterfaceParam> children) {
        InterfaceParam id = new InterfaceParam();
        id.setFieldEnName("id");
        id.setFieldName("id");
        id.setMockData("1");
        InterfaceParam pid = new InterfaceParam();
        pid.setFieldEnName("pid");
        pid.setFieldName("pid");
        pid.setMockData("0");
        InterfaceParam name = new InterfaceParam();
        name.setFieldEnName("name");
        name.setFieldName("name");
        name.setMockData("name");
        children.add(id);
        children.add(pid);
        children.add(name);
    }

    private Object getMockData(InterfaceParam interfaceParam, int i) {
        if ("Y".equals(interfaceParam.getIsFieldEnum()) && interfaceParam.getDictId() != null) {
            SysDictType sysDictType = this.sysDictTypeService.selectDictTypeById(interfaceParam.getDictId());
            List<SysDictData> sysDictDatas = new ArrayList<>();
            if (sysDictType != null) {
                SysDictData dictData = new SysDictData();
                dictData.setDictType(sysDictType.getDictType());
                sysDictDatas = this.sysDictDataService.selectDictDataList(dictData);
                if (CollectionUtil.isNotEmpty(sysDictDatas)) {
                    return sysDictDatas.get(i % sysDictDatas.size()).getDictValue();
                }
            }
        }
        if (interfaceParam.getMockData() != null) {
            return interfaceParam.getMockData().toString() + i;
        }
        return null;
    }

    @GetMapping("/queryInterfaceInfo")
    @ResponseBody
    public List<InterfaceInfo> queryInterfaceInfo() {
        InterfaceInfo interfaceInfo = new InterfaceInfo();
        interfaceInfo.setFbType("3");
        List<InterfaceInfo> interfaceInfoList = new ArrayList<>();
        List<InterfaceInfo> dubboList = interfaceInfoService.selectInterfaceInfoList(interfaceInfo);
        if (CollectionUtil.isNotEmpty(dubboList)) {
            for (InterfaceInfo info : dubboList) {
                List<InterfaceParam> requestList = this.interfaceInfoService.paramList("4", info.getId(), "1");
                List<InterfaceParam> responseList = this.interfaceInfoService.paramList("4", info.getId(), "2");
                info.setRequestList(requestList);
                info.setResponseList(responseList);

                // 查询虚拟用况
                queryVirtualUsage(info);
                interfaceInfoList.add(info);
            }
        }

        interfaceInfo.setFbType("2");
        List<InterfaceInfo> bffList = interfaceInfoService.selectInterfaceInfoList(interfaceInfo);
        if (CollectionUtil.isNotEmpty(bffList)) {
            for (InterfaceInfo info : bffList) {
                List<InterfaceParam> requestList = this.interfaceInfoService.paramList("2", info.getId(), "1");
                List<InterfaceParam> responseList = this.interfaceInfoService.paramList("2", info.getId(), "2");
                info.setRequestList(requestList);
                info.setResponseList(responseList);

                // 查询虚拟用况
                queryVirtualUsage(info);
                interfaceInfoList.add(info);
            }
        }
        return interfaceInfoList;
    }

    private void queryVirtualUsage(InterfaceInfo info) {
        VirtualUsage virtualUsage = new VirtualUsage();
        virtualUsage.setRelationInterfaceId(info.getId());
        List<VirtualUsage> virtualUsages = virtualUsageService.selectVirtualUsageList(virtualUsage);
        if (CollectionUtil.isNotEmpty(virtualUsages)) {
            for (VirtualUsage usage : virtualUsages) {
                List<InterfaceParam> requestList = this.interfaceInfoService.paramList("3", usage.getId(), "1");
                List<InterfaceParam> responseList = this.interfaceInfoService.paramList("3", usage.getId(), "2");
                usage.setRequestList(requestList);
                usage.setResponseList(responseList);
            }
        }
        info.setVirtualUsages(virtualUsages);
    }
}
